import React, { useState, useEffect, useMemo, useRef } from 'react';
import { Space, Tag, Button, message, Modal, Tooltip, TreeSelect, Switch, Select, InputNumber, App as AntdApp } from 'antd';
import { MenuOutlined, EditOutlined, DeleteOutlined, EyeOutlined, PlusOutlined, ExclamationCircleOutlined, FolderOutlined, FileOutlined, AppstoreOutlined, CaretRightOutlined, CaretDownOutlined } from '@ant-design/icons';
import * as AntdIcons from '@ant-design/icons';
import { TreeTable } from '@/components/common/TreeTable';
import IconRenderer from '@/components/common/IconRenderer';
import type { Menu, MenuCreateParams, MenuUpdateParams } from '@/api/system';
import type { MenuWithChildren } from '@/types';
import type { TreeOption } from '@/types/common';
import { getMenuTree, createMenu, updateMenu, deleteMenu, getMenuList, getMenuById } from '@/api/system';
import { DynamicForm } from '@/components/common/DynamicForm';
import { createMenuFormConfig } from './components/MenuFormConfig';

const { Option } = Select;

// 使用扩展的Menu类型支持树形结构
interface TreeTableNode extends MenuWithChildren {
  children?: TreeTableNode[];
  level?: number;
  expanded?: boolean;
  hasChildren?: boolean;
}

const Menus: React.FC = () => {
  const { modal } = AntdApp.useApp();
  const [menuFormVisible, setMenuFormVisible] = useState(false);
  const [editingMenu, setEditingMenu] = useState<Menu | null>(null);
  const [viewingMenu, setViewingMenu] = useState<Menu | null>(null);
  const [treeData, setTreeData] = useState<TreeTableNode[]>([]);
  const [loading, setLoading] = useState(false);
  const [searchParams, setSearchParams] = useState<Record<string, unknown>>({});
  const [menuTreeData, setMenuTreeData] = useState<TreeOption[]>([]);
  const [expandedRowKeys, setExpandedRowKeys] = useState<(string | number)[]>([]);

  // 获取菜单树形数据
  const fetchMenuTree = async (params = {}) => {
    setLoading(true);
    try {
      const response = await getMenuTree(params);
      if (response && Array.isArray(response)) {
        const treeData = transformMenuToTreeTableData(response);
        setTreeData(treeData);
      }
    } catch (error) {
      message.error('菜单数据加载失败');
    } finally {
      setLoading(false);
    }
  };

  // 获取菜单树数据（用于表单选择）
  const fetchMenuTreeForForm = async () => {
    try {
      const response = await getMenuList();
      if (response && Array.isArray(response)) {
        const treeData = transformMenuToTree(response);
        setMenuTreeData(treeData);
      }
    } catch (error) {
      // 静默处理获取菜单树失败
    }
  };

  // 将API返回的菜单数据转换为树形表格数据格式
  // 使用any类型接收API数据，因为API返回的数据已包含children属性
  const transformMenuToTreeTableData = (menus: MenuWithChildren[]): TreeTableNode[] => {
    // 首先检查是否已经是树形结构
    const hasTreeStructure = menus.some(menu => menu.children && Array.isArray(menu.children));

    if (hasTreeStructure) {
      // 如果已经是树形结构，直接转换，但不设置level（让TreeTable处理）
      const transformNode = (node: Menu): TreeTableNode => {
        const children = node.children ? node.children.map(child => transformNode(child)) : [];
        return {
          ...node,
          children: children.length > 0 ? children : undefined,
          hasChildren: children.length > 0,
        };
      };
      return menus.map(node => transformNode(node));
    }

    // 如果是扁平化数据，构建树形结构
    const buildTree = (parentId: string | number): TreeTableNode[] => {
      const parentIdStr = String(parentId);
      const children = menus.filter(menu => String(menu.pid) === parentIdStr);
      
      return children.map(menu => {
        const subChildren = buildTree(menu.id);
        const node = {
          ...menu,
          children: subChildren.length > 0 ? subChildren : undefined,
          hasChildren: subChildren.length > 0,
        };
        return node;
      });
    };
    
    // 尝试不同的根节点值
    let treeData = buildTree(0);
    if (treeData.length === 0) {
      treeData = buildTree("0");
    }
    if (treeData.length === 0) {
      // 尝试查找pid为null的节点
      const rootNodes = menus.filter(menu => !menu.pid || menu.pid === null);
      treeData = rootNodes.map(menu => {
        const children = buildTree(menu.id);
        return {
          ...menu,
          children: children.length > 0 ? children : undefined,
          hasChildren: children.length > 0,
        };
      });
    }
    
    return treeData;
  };

  // 将菜单数据转换为树形结构（用于表单）
  const transformMenuToTree = (menus: MenuWithChildren[]): TreeOption[] => {
    const buildTree = (parentId: string | number): TreeOption[] => {
      return menus
        .filter(menu => String(menu.pid) === String(parentId))
        .map(menu => ({
          title: menu.name,
          value: menu.id,
          key: menu.id,
          children: buildTree(menu.id),
        }));
    };
    const treeData = buildTree(0);
    return treeData;
  };

  // 初始化加载数据
  useEffect(() => {
    fetchMenuTree();
    fetchMenuTreeForForm();
  }, []);

  // 当 treeData 变化时，如果 expandedRowKeys 为空，则初始化展开状态
  // 但只在初始加载时执行，避免覆盖用户的展开/折叠操作
  const hasInitialized = useRef(false);
  useEffect(() => {
    // 自动展开所有节点（初始化时）
    if (treeData.length > 0 && expandedRowKeys.length === 0 && !hasInitialized.current) {
      const getAllKeys = (nodes: TreeTableNode[]): (string | number)[] => {
        const keys: (string | number)[] = [];

        function traverse(items: TreeTableNode[]) {
          items.forEach(item => {
            keys.push(item.id);
            if (item.children && item.children.length > 0) {
              traverse(item.children);
            }
          });
        }

        traverse(nodes);
        return keys;
      };

      const allKeys = getAllKeys(treeData);
      setExpandedRowKeys(allKeys);
      hasInitialized.current = true;
    }
  }, [treeData]);

  

  // 使用useCallback避免函数重新创建
  const handleExpandedRowsChange = React.useCallback((newExpandedRowKeys: (string | number)[]) => {
    setExpandedRowKeys([...newExpandedRowKeys]);
  }, []);

  // 表格列定义 - 使用useMemo避免闭包陷阱
  const columns = useMemo(() => [
    {
      key: 'name',
      title: '菜单名称',
      dataIndex: 'name',
      width: 350,
      render: (text: string, record: Menu, index: number, level: number) => {
        // 从record中直接获取属性
        const hasChildren = record.hasChildren || (record.children && record.children.length > 0);
        
        // 检查当前节点是否展开
        const isExpanded = expandedRowKeys.includes(record.id);

        const handleExpandClick = (e: React.MouseEvent) => {
          e.stopPropagation();
          
          // 使用函数式更新来确保获取最新的状态
          setExpandedRowKeys(prevKeys => {
            const isCurrentlyExpanded = prevKeys.includes(record.id);
            
            let newKeys;
            if (isCurrentlyExpanded) {
              // 当前展开，点击后折叠
              newKeys = prevKeys.filter(key => key !== record.id);
            } else {
              // 当前折叠，点击后展开
              newKeys = [...prevKeys, record.id];
            }
            
            // 异步调用handleExpandedRowsChange
            setTimeout(() => {
              handleExpandedRowsChange(newKeys);
            }, 0);
            
            return newKeys;
          });
        };

        return (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {/* 层级缩进 */}
            <div style={{ width: level * 20 }} />

            {/* 展开/折叠按钮 */}
            {hasChildren && (
              <Button
                type="text"
                size="small"
                icon={isExpanded ? <CaretDownOutlined /> : <CaretRightOutlined />}
                onClick={handleExpandClick}
                style={{
                  padding: 0,
                  width: 16,
                  height: 16,
                  fontSize: '12px',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center'
                }}
              />
            )}
            {!hasChildren && (
              <div style={{ width: 16 }} />
            )}

            {/* 菜单图标 */}
            {record.type === 'M' ? <FolderOutlined /> :
             record.type === 'C' ? <FileOutlined /> : <AppstoreOutlined />}

            {/* 菜单名称 */}
            <span style={{ fontWeight: level === 0 ? 600 : 400 }}>
              {text}
            </span>
          </div>
        );
      },
    },
    {
      key: 'icon',
      title: '图标',
      dataIndex: 'icon',
      width: 120,
      render: (icon: string) => (
        <IconRenderer
          icon={icon}
          size={16}
          showName={true}
        />
      ),
    },
    {
      key: 'path',
      title: '路径',
      dataIndex: 'path',
      width: 200,
      ellipsis: true,
      render: (text: string) => text || '-',
    },
    {
      key: 'component',
      title: '组件',
      dataIndex: 'component',
      width: 180,
      ellipsis: true,
      render: (text: string) => text || '-',
    },
    {
      key: 'permission',
      title: '权限标识',
      dataIndex: 'permission',
      width: 180,
      ellipsis: true,
      render: (text: string) => text || '-',
    },
    {
      key: 'type',
      title: '类型',
      dataIndex: 'type',
      width: 100,
      render: (type: string) => {
        const typeMap = {
          'M': { color: 'blue', text: '目录' },
          'C': { color: 'green', text: '菜单' },
          'F': { color: 'orange', text: '按钮' },
        };
        const config = typeMap[type as keyof typeof typeMap] || { color: 'default', text: type };
        return <Tag color={config.color}>{config.text}</Tag>;
      },
    },
    {
      key: 'visible',
      title: '显示',
      dataIndex: 'visible',
      width: 100,
      render: (visible: boolean) => (
        <Tag color={visible ? 'green' : 'red'}>
          {visible ? '显示' : '隐藏'}
        </Tag>
      ),
    },
    {
      key: 'status',
      title: '状态',
      dataIndex: 'status',
      width: 100,
      render: (status: boolean) => (
        <Tag color={status ? 'green' : 'red'}>
          {status ? '正常' : '停用'}
        </Tag>
      ),
    },
    {
      key: 'sort',
      title: '排序',
      dataIndex: 'sort',
      width: 80,
      render: (sort: number) => sort || 0,
    },
    {
      key: 'createTime',
      title: '创建时间',
      dataIndex: 'createTime',
      width: 160,
      render: (text: string) => text ? new Date(text).toLocaleString() : '-',
    },
  ], [expandedRowKeys, handleExpandedRowsChange]); // 确保columns随expandedRowKeys更新


  // 节点操作按钮
  const nodeActions = [
    {
      key: 'add',
      label: '添加',
      icon: <PlusOutlined />,
      onClick: (record: Menu) => {
        setEditingMenu({ ...record, pid: record.id } as Menu);
        setMenuFormVisible(true);
      },
      visible: (record: Menu) => record.type !== 'F', // 按钮类型不能添加子节点
    },
    {
      key: 'edit',
      label: '编辑',
      icon: <EditOutlined />,
      onClick: async (record: Menu) => {
        try {
          setLoading(true);
          // 调用 getMenuById 获取完整的菜单数据
          const response = await getMenuById(record.id);
          if (response) {
            setEditingMenu(response);
            setMenuFormVisible(true);
          } else {
            message.error('获取菜单数据失败');
          }
        } catch (error) {
          message.error('获取菜单数据失败');
          console.error('获取菜单数据失败:', error);
        } finally {
          setLoading(false);
        }
      },
    },
    {
      key: 'delete',
      label: '删除',
      icon: <DeleteOutlined />,
      danger: true,
      onClick: (record: Menu) => {
        handleDeleteMenu(record);
      },
    },
    {
      key: 'view',
      label: '查看',
      icon: <EyeOutlined />,
      onClick: (record: Menu) => {
        setViewingMenu(record);
      },
    },
  ];

  // 搜索字段
  const searchFields = [
    {
      key: 'name',
      label: '菜单名称',
      type: 'input',
      placeholder: '请输入菜单名称',
    },
    {
      key: 'path',
      label: '菜单路径',
      type: 'input',
      placeholder: '请输入菜单路径',
    },
    {
      key: 'type',
      label: '菜单类型',
      type: 'select',
      placeholder: '请选择菜单类型',
      options: [
        { label: '目录', value: 'M' },
        { label: '菜单', value: 'C' },
        { label: '按钮', value: 'F' },
      ],
    },
    {
      key: 'visible',
      label: '是否显示',
      type: 'select',
      placeholder: '请选择是否显示',
      options: [
        { label: '显示', value: true },
        { label: '隐藏', value: false },
      ],
    },
    {
      key: 'status',
      label: '菜单状态',
      type: 'select',
      placeholder: '请选择菜单状态',
      options: [
        { label: '正常', value: true },
        { label: '停用', value: false },
      ],
    },
  ];

  // 处理搜索
  const handleSearch = (params: Record<string, unknown>) => {
    setSearchParams(params);
    fetchMenuTree(params);
  };

  // 处理重置搜索
  const handleResetSearch = () => {
    setSearchParams({});
    fetchMenuTree();
  };

  // 删除菜单
  const handleDeleteMenu = (menu: Menu) => {
    modal.confirm({
      title: '确认删除',
      content: `确定要删除菜单 "${menu.name}" 吗？`,
      icon: <ExclamationCircleOutlined />,
      onOk: async () => {
        try {
          await deleteMenu(menu.id);
          message.success('删除成功');
          fetchMenuTree(searchParams);
          await fetchMenuTreeForForm();
        } catch (error) {
          message.error('删除失败');
        }
      },
    });
  };

  // 创建菜单
  const handleCreateMenu = () => {
    setEditingMenu(null);
    setMenuFormVisible(true);
  };

  // 处理表单关闭
  const handleFormCancel = () => {
    setMenuFormVisible(false);
    setEditingMenu(null);
  };

  // 处理表单提交
  const handleFormSubmit = async (values: MenuCreateParams | MenuUpdateParams) => {
    try {
      if (editingMenu) {
        // 更新菜单时需要包含 id 字段
        const updateParams: MenuUpdateParams = {
          ...values,
          id: editingMenu.id
        };
        await updateMenu(updateParams);
        message.success('菜单更新成功');
      } else {
        await createMenu(values as MenuCreateParams);
        message.success('菜单创建成功');
      }
      setMenuFormVisible(false);
      setEditingMenu(null);
      fetchMenuTree(searchParams);
      await fetchMenuTreeForForm();
    } catch (error) {
      message.error(editingMenu ? '菜单更新失败' : '菜单创建失败');
    }
  };

  
  // 生成动态表单配置
  const menuFormConfig = useMemo(() => {
    return createMenuFormConfig(menuTreeData, !!editingMenu);
  }, [menuTreeData, editingMenu]);

  return (
    <div style={{ padding: '16px 20px' }}>
      <TreeTable<Menu>
        columns={columns}
        data={treeData}
        loading={loading}
        nodeActions={nodeActions}
        searchFields={searchFields}
        onSearch={handleSearch}
        scroll={{ x: 'max-content' }}
        pagination={false}
        showExpandColumn={false}
        expandedRowKeys={expandedRowKeys}
        onExpandedRowsChange={handleExpandedRowsChange}
        extra={
          <Button type="primary" icon={<PlusOutlined />} onClick={handleCreateMenu}>
            新增菜单
          </Button>
        }
        refresh={() => fetchMenuTree(searchParams)}
      />

      {/* 菜单表单对话框 */}
      <DynamicForm
        key={`menu-form-${menuTreeData.length}-${editingMenu?.id || 'new'}`}
        config={menuFormConfig}
        values={editingMenu || undefined}
        visible={menuFormVisible}
        onSubmit={handleFormSubmit}
        onCancel={handleFormCancel}
        width={900}
      />

      {/* 菜单详情对话框 */}
      <Modal
        title="菜单详情"
        open={!!viewingMenu}
        onCancel={() => setViewingMenu(null)}
        footer={null}
        width={800}
      >
        {viewingMenu && (
          <div style={{ padding: '20px 0' }}>
            <Space direction="vertical" style={{ width: '100%' }} size="middle">
              <div>
                <strong>菜单名称：</strong>
                <span style={{ marginLeft: 8 }}>{viewingMenu.name}</span>
              </div>
              <div>
                <strong>父级菜单：</strong>
                <span style={{ marginLeft: 8 }}>{viewingMenu.pid === 0 ? '顶级菜单' : viewingMenu.pid}</span>
              </div>
              <div>
                <strong>菜单图标：</strong>
                <span style={{ marginLeft: 8 }}>
                  <IconRenderer
                    icon={viewingMenu.icon || ''}
                    size={18}
                    showName={true}
                  />
                </span>
              </div>
              <div>
                <strong>路由路径：</strong>
                <span style={{ marginLeft: 8 }}>{viewingMenu.path || '-'}</span>
              </div>
              <div>
                <strong>组件路径：</strong>
                <span style={{ marginLeft: 8 }}>{viewingMenu.component || '-'}</span>
              </div>
              <div>
                <strong>权限标识：</strong>
                <span style={{ marginLeft: 8 }}>{viewingMenu.permission || '-'}</span>
              </div>
              <div>
                <strong>菜单类型：</strong>
                <span style={{ marginLeft: 8 }}>
                  {viewingMenu.type === 'M' ? '目录' : viewingMenu.type === 'C' ? '菜单' : '按钮'}
                </span>
              </div>
              <div>
                <strong>是否显示：</strong>
                <span style={{ marginLeft: 8 }}>
                  {viewingMenu.visible ? '显示' : '隐藏'}
                </span>
              </div>
              <div>
                <strong>菜单状态：</strong>
                <span style={{ marginLeft: 8 }}>
                  {viewingMenu.status ? '正常' : '停用'}
                </span>
              </div>
              <div>
                <strong>排序：</strong>
                <span style={{ marginLeft: 8 }}>{viewingMenu.sort}</span>
              </div>
              <div>
                <strong>创建时间：</strong>
                <span style={{ marginLeft: 8 }}>
                  {viewingMenu.createTime ? new Date(viewingMenu.createTime).toLocaleString() : '-'}
                </span>
              </div>
              <div>
                <strong>更新时间：</strong>
                <span style={{ marginLeft: 8 }}>
                  {viewingMenu.updateTime ? new Date(viewingMenu.updateTime).toLocaleString() : '-'}
                </span>
              </div>
              {viewingMenu.remark && (
                <div>
                  <strong>备注：</strong>
                  <span style={{ marginLeft: 8 }}>{viewingMenu.remark}</span>
                </div>
              )}
            </Space>
          </div>
        )}
      </Modal>
    </div>
  );
};

export default Menus;